﻿using System.Collections.Concurrent;
using System.Collections.Generic;

namespace RemoteSensingImageDirectServer.Untils.ScopeSpace
{
    public class RasterHistogram
    {
        /// <summary>
        /// 像元个数
        /// </summary>
        public long PixelCount { get; set; }

        /// <summary>
        /// 此直方图中的最小值
        /// </summary>
        private readonly int MinValue;

        /// <summary>
        /// 此直方图中的最大值
        /// </summary>
        private readonly int MaxValue;

        /// <summary>
        /// 是否被统计
        /// </summary>
        private readonly bool IsStatictis;

        /// <summary>
        /// 直方图
        /// </summary>
        private int[] Historam { get; set; }

        /// <summary>
        /// 存储直方图百分比相关节点上的值的字典
        /// </summary>
        private ConcurrentDictionary<double, int> Extremes { get; set; }

        public RasterHistogram()
        {
            Extremes = new ConcurrentDictionary<double, int>();
        }

        /// <summary>
        /// 获取最小值
        /// </summary>
        /// <returns></returns>
        public int GetMinValue()
        {
            return MinValue;
        }

        /// <summary>
        /// 获取最大值
        /// </summary>
        /// <returns></returns>
        public int GetMaxValue()
        {
            return MaxValue;
        }

        /// <summary>
        /// 根据百分比获取直方图的值
        /// </summary>
        /// <param name="percent">百分比数值</param>
        /// <returns>百分比数值下的直方图的映射值</returns>
        public int GetPercentValue(double percent)
        {
            if (!this.Extremes.TryGetValue(percent, out int value))
            {
                if (percent <= 50)
                {
                    this.Extremes.TryAdd(percent, HistogramLeft2Right(percent));
                }
                else
                {
                    this.Extremes.TryAdd(percent, HistogramRight2Left(percent));
                }
            }
            return value;
        }

        /// <summary>
        /// 从左往右查找百分比拉伸值
        /// </summary>
        /// <param name="percent">百分比数值</param>
        /// <returns>百分比数值下的直方图的映射值</returns>
        private int HistogramLeft2Right(double percent)
        {
            int value;
            long realTotalPixelsCount = this.PixelCount - this.Historam[0];//去除最小值后的实际像素值

            var leftTrimCount = realTotalPixelsCount * percent / 100.0;//计算左边开始位置

            long count = 0;

            int j = 1;
            while (j < this.Historam.Length && count < leftTrimCount)
                count += this.Historam[j++];

            value = j - 1;

            return value;
        }

        /// <summary>
        /// 从右往左查询百分比拉伸值
        /// </summary>
        /// <param name="percent">百分比数值</param>
        /// <returns>百分比数值下的直方图的映射值</returns>
        private int HistogramRight2Left(double percent)
        {
            int value;

            long realTotalPixelsCount = this.PixelCount - this.Historam[0];

            var rightTrimCount = realTotalPixelsCount * percent / 100.0;//计算右边结束位置

            int j = this.Historam.Length - 1;
            long count = 0;
            while (j >= 1 && count < rightTrimCount)
                count += this.Historam[j--];

            value = j;

            if (value == 0)
                value = (int)(255 * (100 - percent));

            return value;
        }


    }
}
